package com.lzb.basic.utils;

import android.graphics.Bitmap;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMetadataRetriever;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import com.lzb.basic.bean.MediaMetadataInfo;

import java.io.IOException;


/**
 * Desc: 媒体相关工具类
 */
public class MediaUtil {

    private static final String TAG = MediaUtil.class.getSimpleName();

    /**
     * 查找视频轨道
     *
     * @param extractor
     * @return
     */
    public static int selectVideoTrack(@NonNull MediaExtractor extractor) {
        int numTracks = extractor.getTrackCount();
        for (int i = 0; i < numTracks; i++) {
            MediaFormat format = extractor.getTrackFormat(i);
            String mime = format.getString(MediaFormat.KEY_MIME);
            if (mime.startsWith("video/")) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 获取视频的第一帧
     * @param videoPath 视频文件路径
     * @return 第一帧的Bitmap，如果获取失败返回null
     */
    public static Bitmap getVideoFirstFrame(String videoPath) {
        if (TextUtils.isEmpty(videoPath)) {
            return null;
        }
        
        MediaMetadataRetriever retriever = null;
        try {
            retriever = new MediaMetadataRetriever();
            retriever.setDataSource(videoPath);
            // 获取第一帧（时间位置为0微秒）
            Bitmap frame = retriever.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
            return frame;
        } catch (Exception e) {
            Log.e(TAG, "Failed to get video first frame: " + e.getMessage());
            return null;
        } finally {
            if (retriever != null) {
                try {
                    retriever.release();
                } catch (Exception e) {
                    Log.e(TAG, "Failed to release MediaMetadataRetriever: " + e.getMessage());
                }
            }
        }
    }

    /**
     * 查找音频轨道
     *
     * @param extractor
     * @return
     */
    public static int selectAudioTrack(@NonNull MediaExtractor extractor) {
        int numTracks = extractor.getTrackCount();
        for (int i = 0; i < numTracks; i++) {
            MediaFormat format = extractor.getTrackFormat(i);
            String mime = format.getString(MediaFormat.KEY_MIME);
            if (mime.startsWith("audio/")) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 获取filePath文件的时长
     *
     * @param filePath 音视频文件路径
     * @return 时长 单位：毫秒
     */
    public static long getDuration(String filePath) {
        try {
            MediaExtractor mediaExtractor = new MediaExtractor();
            mediaExtractor.setDataSource(filePath);
            int trackIdx = selectVideoTrack(mediaExtractor);
            if (trackIdx == -1) {
                trackIdx = selectAudioTrack(mediaExtractor);
                if (trackIdx == -1) {
                    return 0;
                }
            }
            MediaFormat mediaFormat = mediaExtractor.getTrackFormat(trackIdx);
            long duration = mediaFormat.containsKey(MediaFormat.KEY_DURATION) ? mediaFormat.getLong(MediaFormat.KEY_DURATION) : 0;
            duration = duration / 1000; //微妙转换为毫秒
            mediaExtractor.release();
            return duration;
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 获取媒体元数据信息
     *
     * @param path
     * @return
     */
    public static MediaMetadataInfo getMediaMetadataInfo(String path) {
        MediaMetadataRetriever retriever = null;
        MediaMetadataInfo metadataInfo = null;
        try {
            retriever = new MediaMetadataRetriever();
            retriever.setDataSource(path);

            metadataInfo = new MediaMetadataInfo();
            //bitrate
            String value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE);
            if (!TextUtils.isEmpty(value)) {
                metadataInfo.setBitrate((int) Str2NumUtil.parse(value));
            }
            //width
            value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
            if (!TextUtils.isEmpty(value)) {
                Log.i(TAG, "getMediaMetadataInfo: video width = " + value);
                metadataInfo.setWidth((int) Str2NumUtil.parse(value));
            }
            value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_IMAGE_WIDTH);
            if (!TextUtils.isEmpty(value)) {
                Log.i(TAG, "getMediaMetadataInfo: image width = " + value);
                metadataInfo.setWidth((int) Str2NumUtil.parse(value));
            }
            //height
            value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
            if (!TextUtils.isEmpty(value)) {
                metadataInfo.setHeight((int) Str2NumUtil.parse(value));
            }
            value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_IMAGE_HEIGHT);
            if (!TextUtils.isEmpty(value)) {
                metadataInfo.setHeight((int) Str2NumUtil.parse(value));
            }
            //duration
            value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
            if (!TextUtils.isEmpty(value)) {
                Log.i(TAG, "getMediaMetadataInfo: duration = " + value);
                metadataInfo.setDuration((int) Str2NumUtil.parse(value));
            }
            //sample rate
            value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_SAMPLERATE);
            if (!TextUtils.isEmpty(value)) {
                Log.i(TAG, "getMediaMetadataInfo: sample rate = " + value);
                metadataInfo.setSampleRate((int) Str2NumUtil.parse(value));
            }
            //mimeType
            value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
            if (!TextUtils.isEmpty(value)) {
                Log.i(TAG, "getMediaMetadataInfo: mimeType = " + value);
                metadataInfo.setMimeType(value);
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            if (retriever != null) {
                try {
                    retriever.release();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return metadataInfo;
    }

}
